﻿using System;
using System.Collections.Generic;
using System.Linq;
using FH.Core.IRepositories;
using FH.Core.Entities;
using FH.Core;
using Microsoft.Extensions.Caching.Distributed;
using System.Reflection;
using FH.Extensions;
using FH.Application.BannerApp.Dtos;
using AutoMapper;

namespace FH.Application.UserApp
{
    /// <summary>
    /// 用户管理服务
    /// </summary>
    public class SettingService : ISettingService
    {
        private readonly IDistributedCache _cacheManager;
        private readonly ISettingRepository _repository;
        private readonly ICustomerRepository _customerRepository;
        private readonly IBannerRepository _bannerRepository;
        /// <summary>
        /// 构造函数 实现依赖注入
        /// </summary>
        /// <param name="userRepository">仓储对象</param>
        public SettingService(ISettingRepository repository,
            IBannerRepository bannerRepository
            , ICustomerRepository customerRepository
            , IDistributedCache cacheManager)
        {
            _repository = repository;
            _bannerRepository = bannerRepository;
            _customerRepository = customerRepository;
            _cacheManager = cacheManager;
        }
        public AppConfig GetAppConfig()
        {
            return _cacheManager.Get<AppConfig>("FH_Setting_AppConfig", () =>
            {
                AppConfig config = new AppConfig();
                IEnumerable<Setting> appSettings = _repository.Tables.Where(r => r.Name.Contains("FH_Setting_Config_"))
                    .ToList();
                PropertyInfo[] properties = config.GetType().GetProperties();
                if (properties != null && properties.Any())
                {
                    Setting setting = null;
                    string name = string.Empty;
                    List<Setting> addSettings = new List<Setting>();
                    foreach (PropertyInfo item in properties)
                    {
                        name = "FH_Setting_Config_" + item.Name;
                        setting = appSettings.FirstOrDefault(r => r.Name == name);
                        if (setting != null)
                        {
                            item.SetValue(config, setting.Value.CastTo(item.PropertyType));
                        }
                        else
                        {
                            string value = item.GetType().IsValueType ? Activator.CreateInstance(item.GetType()).ToString() : null;
                            addSettings.Add(new Setting(name, value));
                        }
                    }
                    if (addSettings != null && addSettings.Any())
                    {
                        foreach(Setting item in addSettings)
                        {
                            _repository.Insert(item);
                        }
                        
                    }
                }
                return config;
            }, (int)TimeSpan.FromHours(2).TotalSeconds);
        }
        public void UpdateAppConfig(AppConfig config)
        {
            IEnumerable<Setting> appSettings =_repository.Tables.Where(r => r.Name.Contains("FH_Setting_Config_"))
                .ToList();
            PropertyInfo[] properties = config.GetType().GetProperties();
            if (properties != null && properties.Any())
            {
                Setting setting = null;
                string name = string.Empty;
                foreach (PropertyInfo item in properties)
                {
                    name = "FH_Setting_Config_" + item.Name;
                    setting = appSettings.FirstOrDefault(r => r.Name == name);
                    if (setting != null)
                    {
                        setting.Value = item.GetValue(config, null)?.ToString();
                    }
                }
                foreach (Setting item in appSettings)
                {
                    _repository.Update(item);
                }
                //_configRepository.UpdateRange(appSettings);
                _cacheManager.Remove("FH_Setting_AppConfig");
            }
        }
        #region 广告
        public List<BannerDto> GetBannerPage(int startPage, int pageSize, out int rowCount)
        {
            return Mapper.Map<List<BannerDto>>(_bannerRepository.LoadPageList(startPage, pageSize, out rowCount, null, it => it.CreatedOn));
        }
        public BannerDto InsertOrUpdate(BannerDto dto)
        {
            if (Get(dto.Id) != null)
                _repository.Delete(dto.Id);
            var user = _bannerRepository.InsertOrUpdate(Mapper.Map<Banner>(dto));
            return Mapper.Map<BannerDto>(user);
        }
        public BannerDto Get(Guid id)
        {
            return Mapper.Map<BannerDto>(_bannerRepository.Get(id));
        }
        /// <summary>
        /// 根据Id集合批量删除
        /// </summary>
        /// <param name="ids">Id集合</param>
        public void DeleteBatch(List<Guid> ids)
        {
            _bannerRepository.Delete(it => ids.Contains(it.Id));
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id">Id</param>
        public void Delete(Guid id)
        {
            _bannerRepository.Delete(id);
        }
        #endregion

        #region 客户
        public List<CustomerDto> GetCustomerPage(int startPage, int pageSize, out int rowCount)
        {
            return Mapper.Map<List<CustomerDto>>(_customerRepository.LoadPageList(startPage, pageSize, out rowCount, null, it => it.CreatedOn));
        }
        public CustomerDto InsertOrUpdateCustomer(CustomerDto dto)
        {
            if (GetCustomer(dto.Id) != null)
                _customerRepository.Delete(dto.Id);
            var user = _customerRepository.InsertOrUpdate(Mapper.Map<Customer>(dto));
            return Mapper.Map<CustomerDto>(user);
        }
        public CustomerDto GetCustomer(Guid id)
        {
            return Mapper.Map<CustomerDto>(_customerRepository.Get(id));
        }
        /// <summary>
        /// 根据Id集合批量删除
        /// </summary>
        /// <param name="ids">Id集合</param>
        public void DeleteBatchCustomer(List<Guid> ids)
        {
            _customerRepository.Delete(it => ids.Contains(it.Id));
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id">Id</param>
        public void DeleteCustomer(Guid id)
        {
            _customerRepository.Delete(id);
        }
        #endregion
    }
}
